

"""
Base Classes
A file for all the various base classes, interfaces, etc.
"""

from pgEngine import directions
from pgEngine.movementData import Plot, Move
from pgEngine.point import Point
from pgEngine.utils import frange

class MovableItem(object):
    direction = directions.North
    speedInfo = None
    ocean = None
    _plot=None
    animate_hook = None
    
    #animation vars removed from disuse

    def __init__(self, ocean, initLoc=Point(0.0, 0.0), initDir=directions.North):
        self.direction = initDir
        self.ocean = ocean
        self.ocean.append(self, initLoc)
        self.endAnim = False

    def getMaxMove(self, direction):
        """
        A standardized convenience function. Returns the max distance movable in
        the given direction. Not implemented here to ensure that derived classes
        implement it correctly for their class.
        """
        raise NotImplementedError, 'You need to implement getMaxMove() yourself.'

    def getAutoMove(self):
        """
        Sets an automatically-generated move for the current turn. Not
        implemented due to variety of cases in pgame.
        """
        raise NotImplementedError, 'You need to implement getAutoMove() yourself.'

    def getPotentialMoves(self):
        """
        Returns a list of the distances self could move, given the currently
        assigned plot. Not implemented due to variety of cases in pgame.
        """
        raise NotImplementedError, 'You need to implement getPotentialMoves() yourself.'

    def validatePlot(self):
        """
        Called on plot modification, ensures the currently plotted move is still
        valid. Not implemented due to variety of cases in pgame.
        """
        raise NotImplementedError, 'You need to implement validatePlot() yourself.'

    def move(self):
        """
        Moves the currently plotted move without animation.
        """
        # Validate our plot
        newplot = self._plot
        assert newplot.owner is self, "Not our plot!"
        # Make sure we have an iterable collection of moves
        if not hasattr(newplot, '__iter__'):
            newplot = [ newplot ]
        if len(newplot) == 0:
            newplot = [ self.getAutoMove() ]
        for vector in self._plot:
            #We assume the plot is valid.
            self.ocean.moveItem(self, vector)
        self.direction = vector.dir
        self._plot = Plot(self, [])

    #animateStep() and startAnim() removed due to code duplication

    def animate(self, percentInc=5.0):
        """
        A generator for animating this object.
        """
        
        newplot = self._plot
        #print "Plots:", newplot

        if not hasattr(newplot, '__iter__'):
            newplot = [ newplot ]

        if len(newplot) == 0:
            newplot = [ self.getAutoMove() ]

        for move in newplot:
            totDist = move.dist
            dir = move.dir
            distInc = percentInc / 100.0 * self.getMaxMove(move.dir)
            
            for currDist in frange(0, totDist+distInc, distInc):
                newPos = self.ocean.moveItem(self, Move(dir, distInc))
                self.direction = dir
                if self.animate_hook is not None:
                    self.animate_hook(newpos)
                yield newPos
             
            #print "At the end of the leg"

        self.direction = move.dir
        self._plot = Plot(self, [])
        #print "At the end of the plot"

